/*
  S.M.A.C.K - An operating system kernel
  Copyright (C) 2010,2011 Mattias Holm and Kristian Rietveld
  For licensing and a full list of authors of the kernel, see the files
  COPYING and AUTHORS.
*/

#ifndef KERNEL__ARM_PROCESS_H
#define KERNEL__ARM_PROCESS_H

#include <stdint.h>
#include <sys/types.h> // For pid_t
#include <arch-types.h> // For pa_t
#include <vfs/vfs.h>

#define PROC_MAX 32
#define PROC_MAX_FILES 16
#define MAX_ADDR_SPACES 255

// NOTE: cpu_ctxt_t MUST CONFORM TO THE SAME LAYOUT AS THE ISR as well
// as cswitch.
// TODO: Fix layout
typedef struct {
  uint32_t gprs[15]; // User registers
  uint32_t pc;
  uint32_t svc_sp; // lr and sp for svc mode
  uint32_t svc_lr;
  uint32_t spsr;
  uint32_t dummy; // Even number of words
} cpu_ctxt_t;

typedef struct {
  pa_t ttbr0;
  va_t ttbr0_va;
  va_t svc_stack;
} cpu_helper_t;

/*
  Context switches can happen at very few destinct occations:
  1. As the result of a timer interrupt
  2. As the result of a system call that blocks the process

  The first event, would take a task from running to idle, meaining that the task
  is ready for scheduling.

  The second event would take the task from running to blocked.

  The two different switches that can occur need to be handled a little bit differently.

  When a timer interrupt results in a context switch, we must return from the timer
  interrupt, or our interrupt stack will overflow at some point. When the process is
  blocked as the result of a system call, then we actually want to return to the system
  code. The system code needs its own svc stack.

  Note that all the other exceptions are fatal for the currently executing process.
*/

/*
  The cswitch routine switch the context from the currrent thread to the one passed
  in to the routine in r0.

  The cswitch routine will return, but not now. It will return when the process is ready
  for scheduling again.
*/
void cswitch(proc_t *new, proc_t *old);
void hw_proc_start(void);
void hw_return_from_fork(void);


#endif /* !KERNEL__ARM_PROCESS_H */
